class TeamMate extends ps.Behaviour {
  /** 序列化 */
  private serializableFields: Object = {
    isHorse: qc.Serializer.BOOLEAN,
    life: qc.Serializer.NUMBER,
    attackInterval: qc.Serializer.NUMBER,
    speed: qc.Serializer.NUMBER,
  };

  constructor(gameObject: qc.Node) {
    super(gameObject);
  }

  life: number;
  isHorse: boolean = false;
  price: number;
  mc: ps.MovieClip;
  onInit() {
    this.getMc();
  }

  getMc() {
    this.mc = this.gameObject.getScript(ps.MovieClip);
  }

  walk() {
    if (!this.mc) this.getMc();
    if (this.isHorse) {
      this.mc.gotoAndPlay("xlz_horse_walk/xlz_horse_walk_", -1);
    } else {
      this.mc.gotoAndPlay("xlz_bow_walk/xlz_bow_walk_", -1);
    }
  }

  attack() {
    if (!this.mc) this.getMc();
    if (this.isHorse) {
      this.mc.gotoAndPlay("xlz_horse_attack/xlz_horse_attack_", -1);
    } else {
      this.mc.gotoAndPlay("xlz_bow_attack/xlz_bow_attack_", -1);
    }
  }

  die() {
    if (!this.mc) this.getMc();
    if (this.isHorse) {
      this.mc.gotoAndPlay("xlz_horse_die/xlz_horse_die_", 1, () => {
        Tween.hideAlpha(this.gameObject, 500, 0, "remove");
      });
    } else {
      this.mc.gotoAndPlay("xlz_bow_die/xlz_bow_die_", 1, () => {
        Tween.hideAlpha(this.gameObject, 500, 0, "remove");
      });
    }
    ps.Audio.playSound(`sound_die_${Random.range(1, 8, "round")}`);
  }

  idle() {
    if (!this.mc) this.getMc();
    if (this.isHorse) {
      this.mc.gotoAndPlay("xlz_horse_idle/xlz_horse_idle_", -1);
    } else {
      this.mc.gotoAndPlay("xlz_bow_idle/xlz_bow_idle_", -1);
    }
  }

  getNearest() {
    let minDistance: number = Number.MAX_VALUE;
    let target: qc.Node;
    const myPos: qc.Point = this.gameObject.getWorldPosition();
    main.enemies.forEach((m) => {
      const distance: number = m.getWorldPosition().distance(myPos);
      if (distance < minDistance) {
        minDistance = distance;
        target = m;
      }
    });
    return {
      target,
      distance: minDistance,
    };
  }

  attacking: boolean = false;
  speed: number = 2;
  attackInterval: number;
  attackLoop: qc.TimerEvent;

  hurt() {
    if (this.life <= 0) return;
    this.life--;
    main.progressWei.value--;
    if (this.life <= 0) {
      this.attacking = false;
      this.attackTarget = null;
      main.team.splice(main.team.indexOf(this.gameObject), 1);
      this.die();
      if (this.shootInterval) {
        this.game.timer.remove(this.shootInterval);
      }
    }
  }

  attackTarget: qc.Node;

  shootInterval: qc.TimerEvent;
  startShoot() {
    if (this.isHorse) return;
    this.attack();
    this.shootInterval = this.game.timer.loop(this.attackInterval, () => {
      if (
        !this.attackTarget ||
        (this.attackTarget && this.attackTarget.getScript(EnemyMate).life <= 0)
      ) {
        if (main.enemies.length) {
          main.findTarget(this.gameObject, main.enemies, TeamMate);
        } else {
          this.game.timer.remove(this.shootInterval);
          this.idle();
          this.game.timer.add(1000, () => {
            ps.gameEnd();
          });
        }
      }
      if (this.attackTarget) {
        this.shoot(this.attackTarget);
      }
    });
  }

  shoot(target: qc.Node) {
    if (this.isHorse) return;
    const that = this;
    const bez: ps.Bezier = this.gameObject.getScript(ps.Bezier);
    bez.eventDisp.addOnce(
      BezierEvent.THROW_START,
      (arrow, speedX, speedY, num, allPoint) => {
        const a: qc.Node = this.game.add.clone(arrow);
        a.pivotX = 1;
        let pointIndex: number = 0;
        function follow(point: qc.Point) {
          Tween.to(
            a,
            {
              x: point.x,
              y: point.y,
              rotation: Math.atan2(point.y - a.y, point.x - a.x),
            },
            60
          ).onComplete.addOnce(() => {
            pointIndex++;
            if (pointIndex < allPoint.length) {
              follow(allPoint[pointIndex]);
            } else {
              Tween.hideAlpha(a, 200);
              if (target && target.rectContains(a.getWorldPosition())) {
                const t: EnemyMate = target.getScript(EnemyMate);
                t.hurt();
              }
            }
          });
        }
        a.visible = true;
        a.rotation = Math.atan2(allPoint[0].y - a.y, allPoint[0].x - a.x);
        follow(allPoint[pointIndex]);
      }
    );
    const arrow: qc.Node = this.gameObject.getChild("article");
    const targetPoint: qc.Point = ps.Tools.transPos(target, arrow);
    targetPoint.y -= 30;
    arrow.x = bez.orgPot.x;
    arrow.y = bez.orgPot.y;
    bez.tarPot = targetPoint;
    bez.drawPath();
    bez.powerPot = new qc.Point((targetPoint.x - arrow.x) / 2, Math.min(targetPoint.y,arrow.y) - 100);
    bez.throwStart();
    // ps.Audio.playSound("sound_bow_attack");
    main.playAttackSound('bow')
  }

 

  update() {
    if (!this.isHorse) return;
    if (main.attacking) {
      if (this.attackTarget) {
        if (!this.attacking) {
          if (this.attackLoop) {
            this.game.timer.remove(this.attackLoop);
            this.attackLoop = null;
          }
          if (this.attackTarget.getScript(EnemyMate).life <= 0) {
            main.findTarget(this.gameObject, main.enemies, TeamMate);
          } else {
            main.approach(this.gameObject, this.attackTarget, this.speed);
          }
          if (
            this.attackTarget &&
            main.getDistance(this.gameObject, this.attackTarget) <=
              main.attackMinDistance
          ) {
            main.attackStart(
              this.gameObject,
              TeamMate,
              EnemyMate,
              main.enemies,
              this.attackTarget
            );
          }
        }
      }
    }
  }
}
qc.registerBehaviour("TeamMate", TeamMate);
